{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# 实现简单的线性回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = np.array(list(range(1,6)),dtype=float)\n",
    "y = np.array([1.,3.,2.,3.,5.])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10643b860>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x,y)\n",
    "plt.axis([0,6,0,6])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_mean = np.mean(x)\n",
    "y_mean = np.mean(y)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 分子\n",
    "num = 0.0\n",
    "\n",
    "# 分母\n",
    "d=0.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "for x_i, y_i in zip(x,y):\n",
    "    num += (x_i - x_mean)*(y_i - y_mean)\n",
    "    d += (x_i - x_mean)**2\n",
    "\n",
    "a = num / d\n",
    "b = y_mean - a * x_mean"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 现在已知a和b，把y = ax+b的直线绘制出来"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAW4AAAD8CAYAAABXe05zAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4xLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvAOZPmwAAGDRJREFUeJzt3XuclGX9xvHPV1h1FXVL1wMgoqiLpCG6aobhKV01VDLzUJp5olJLMVfFM1ACoXm2RMRDKKgIaJagmaWkoLuALiJLQBYsGqCtAi64LN/fH/eQ2g/YWZjZZ+6Z6/16+XJ3fKBrGvby8X7ug7k7IiISj82SDiAiIi2j4hYRiYyKW0QkMipuEZHIqLhFRCKj4hYRiUxaxW1mJWY21sxmm9k7ZnZotoOJiMi6tU3zujuAie5+qpltDmyVxUwiIrIB1twCHDPbDpgB7OFarSMikrh07rh3B5YAD5pZd6AauNTdV3z+IjPrC/QF2HrrrQ/s2rVrprOKiOSt6urqpe5ems616dxxlwNTgJ7uPtXM7gA+dvfr1/drysvLvaqqqiWZRUQKmplVu3t5Otem83ByIbDQ3aemvh8LHLCx4UREZNM0W9zu/j6wwMzKUi8dDczKaioREVmvdGeV/BR4NDWjZD5wbvYiiYjIhqRV3O4+A0hr7EVERLJLKydFRCKj4hYRiYyKW0QkMipuEZHIqLhFRCKj4hYRiYyKW0QkMipuEZHIqLhFRCKj4hYRiYyKW0QkMipuEZHIqLhFRCKj4hYRiYyKW0QkMipuEZHIqLhFRCKj4hYRiYyKW0QkMipuEZHIqLhFRCKj4hYRiYyKW0QkMipuEZHIqLhFRCKj4hYRiYyKW0QkMm3TucjM3gWWAU3Aancvz2YoERFZv7SKO+VId1+atSQiIusxYXodwybVsqi+gfYlxVRWlNGnR4ekYyWmJcUtItLqJkyvo/+4GhoamwCoq2+g/7gagIIt73THuB143syqzaxvNgOJiHzesEm1/y3ttRoamxg2qTahRMlL9477MHevM7MdgRfMbLa7v/z5C1KF3hegU6dOGY4pIoVqUX1Di14vBGndcbt7Xervi4HxwMHruGa4u5e7e3lpaWlmU4pIwWpfUtyi1wtBs8VtZlub2TZrvwaOBWZmO5iICEBlRRnFRW2+8FpxURsqK8oSSpS8dIZKdgLGm9na6x9z94lZTSUikrL2AaRmlXym2eJ29/lA91bIIiKyTn16dCjoov5fWjkpIhIZFbeISGRU3CIikVFxi4hERsUtIhIZFbeISGRU3CIikVFxi4hERsUtIhIZFbeISGRU3CIikVFxi4hERsUtIhIZFbeISGRU3CIikVFxi0juW7ECbrkFPvoo6SQ5QcUtIrlr1Sq4807o0gUqK+GZZ5JOlBNU3CKSe1avhhEjYK+94NJLYZ99YPJkOPvspJPlBBW3iOSONWvgscdCUV94IeyyC7zwAvz5z9CzZ9LpcoaKW0SS5w5PPw3du8P3vw/FxeH7KVPgm9+EcFi5pKi4RSQ57vD883DIIdCnTxjTHj0aZsyAk05SYa+HiltEkjF5MhxxBFRUwL//DQ88ALNmwRlnwGaqpg3R/zsi0rqmTYMTToBvfANqa+Guu2DOHDjvPGjbNul0UVBxi0jrmDULTj0VDjwQpk6FoUNh/ny45BLYYouk00VF/3oTkeyaNw8GDIBRo6BdO7jxRujXD7bbLulk0VJxi0h2LFwIv/hFGLsuKoIrroArr4Qddkg6WfRU3CKSWYsXw5AhcO+9YV72j34E114b5mRLRqi4RSQz6uvDfiK33w4NDXDOOXDDDdC5c9LJ8k7axW1mbYAqoM7de2cvkohEZfnysJ/IsGGhvE8/PYxpl5UlnSxvteSO+1LgHWDbLGURkZisXAm//S0MHhyGR048EQYNCqsfJavSmg5oZh2BbwEjshtHRHJeYyMMHx42gOrXD/bbD157Lezcp9JuFenO474duBJYs74LzKyvmVWZWdWSJUsyEk5EckhTU5jSt88+4YHjrruGzZ/+9Cf42teSTldQmi1uM+sNLHb36g1d5+7D3b3c3ctLS0szFlBEEuYO48aFu+mzz4ZttoFnn4W//Q2OPDLpdAUpnTvunsBJZvYuMAY4ysxGZTWViCTPHSZOhIMOgu98J9xxP/EEVFfDt76lDaAS1Gxxu3t/d+/o7p2BM4A/u/tZWU8mIsl5+WXo1QuOPx4++AAeeghqauC739UGUDlAn4CIfOaNN8JufYcfHpaq33tv2AjqnHO0AVQOadEn4e5/Af6SlSQikpyZM+H662HCBNh++7CQ5qKLwoEGknP0r1CRQjZ3btj0afTo8NBx4EC47LLwteQsFbdIIVqwIJT0gw+GLVWvuiqcov7lLyedTNKg4hYpJP/+N9x8c1jxCHDxxdC/P+y8c7K5pEVU3CKF4MMPw14id94ZznU899wwpt2pU9LJZCOouEXy2bJlYbe+W2+Fjz+GM8+Em24Ky9UlWipukXzU0BCm8g0ZAkuXhhPUBw4M+4pI9DSPWySffPppGL/ec89w4swBB8Drr8P48SrtPKLiFskHTU3wyCPQtSv85Cewxx7w17/CpElhybrkFRW3SMzWrIEnn4R99w2rG7/0JXjuuc+WrEteUnGLxMgd/vAHKC+H004L+4eMHQtVVXDccdoAKs+puEVi85e/wGGHQe/e8NFH8LvfwVtvhR38VNgFQcUtEoupU+GYY8Ie2P/8J9x3H8yeDWedBW3aJJ1OWpGKWyTXvfUWnHRSOGXmzTfhttvCHiN9+0JRUdLpJAEqbpFcNWdOWDDTvXt42PiLX8D8+WETqC23TDqdJEgLcERyzT//GRbLPPxwKOhrr4Wf/zzMGBFBxS2SO957L2wAdd99YZbIz34GV18NO+6YdDLJMSpukaR98AEMHQp33w2NjXD++XDdddCxY9LJJEepuEWS8vHH4UHjrbfC8uVhdsiNN0KXLkknkxyn4hZpbZ98AvfcE+6yP/ggzL8eOBC6dUs6mURCs0pEWsuqVaGwu3SBK68Me4hUVYUVjyptaQHdcYtk2+rVYQOogQPDjJFevcL+IocdlnQyiZTuuEWyZc0aePxx+MpXwgPHHXcMu/WtXbIuspFU3CKZ5g6//33YC/uMM2DzzWHChLBk/dhjtZ+IbDIVt0gmvfgiHHpoWKK+YgU89lhYpn7yySpsyRgVt0gmvPYaHHUUfPObsGgR3H8/zJoVlqxvph8zySz9iRLZFDNmhO1Vv/71UNR33AF//ztccIE2gJKsUXGLbIzZs8MBBj16wKuvwuDBMG9eWKa+xRZJp5M81+x0QDPbEngZ2CJ1/Vh3vzHbwaR1TZhex7BJtSyqb6B9STGVFWX06dEh6Vi55x//gAEDwuEFW20F118Pl18OJSWJxtLnV1jSmce9CjjK3ZebWREw2cyec/cpWc4mrWTC9Dr6j6uhobEJgLr6BvqPqwHQD/9aixaFbVVHjAiHFvTrB1ddBaWlSSfT51eAmh0q8WB56tui1F+e1VTSqoZNqv3vD/1aDY1NDJtUm1CiHLJ0KVxxRVjtOGJEGLueNw9uuSUnShv0+RWitFZOmlkboBrYE7jH3aeu45q+QF+ATp06ZTKjZNmi+oYWvV4QPvoobP50221hb5Gzzw4bQO2+e9LJ/h99foUnrYeT7t7k7vsDHYGDzWzfdVwz3N3L3b28NEfuRCQ97UuKW/R6XluxAoYMCQU9aBAcfzzMnAkPPZSTpQ36/ApRi2aVuHs98BJwXHbiSBIqK8ooLvriYbPFRW2orChLKFECVq2CO+8MQyL9+4fpfdOmwRNPwD77JJ1ug/T5FZ50ZpWUAo3uXm9mxcAxwNCsJ5NWs/YBVkHOSmhsDEeEDRwICxaEE9THjw+rHyNR0J9fgTL3DT9nNLOvAg8DbQh36E+4+8AN/Zry8nKvqqrKWEiRjFuzBsaMCePWc+fCIYfAL38JRx+ddDIpUGZW7e7l6Vzb7B23u78F9NjkVCK5wB2efjrMv545E776VXjmmbD6UXuJSCS0clIKgzs8/3y4s/72t+HTT8Md9/TpcOKJKm2Jiopb8t/kyXDEEVBRAYsXw8iR8PbbcPrp2gBKoqQ/tZK/qqvDdL5vfAPmzAmnqNfWwrnnQlsd/iTxUnFL/nn77XAAb3k5vP46/OpXYbXjxRdrAyjJC7rtkPwxbx7cdBM8+ii0axe+7tcPtt026WQiGaXilvgtXBhWOY4cGfbArqwMp6hvv33SyUSyQsUt8Vq8OOyD/ZvfhHnZP/4xXHMN7LJL0slEskrFLfH5z3/C7nx33AErV8I558ANN8BuuyWdTKRVqLglHsuXh7K+5Raorw8nqA8YAHvvnXQykVal4pbct3JlGA4ZPBiWLAknqA8aFFY9ihQgTQeU3NXYCPfdB3vuGY4H694dpkwJS9ZV2lLAVNySe5qawpmOXbuGB4677QYvvQQvvBCWrIsUOBW35A53eOqpcDf9gx/AdtvBH/7w2ZJ1EQFU3JIL3OG558JKx1NPDd8/+SRUVcEJJ2gDKJH/oeKWZP31r9CrVyjo//wnHGpQUxMKXBtAiayTfjIkGW+8AcceG4ZA5s8Ps0Zmzw5DJG3aNPvLRQqZiltaV00N9OkDBx8c9sK+9dZwAs2Pfwybb550OpEoaB63tI6//z0cEzZmTNj0adAguPRS2GabpJOJREfFLdn1r3+Fg3gfeihsqXr11XDFFfDlLyedTCRaKm7Jjvffh5tvDgtoAC65BPr3h512SjaXSB5QcUtmffhhOLjgrrtg1So477xwMO+uuyadTCRvqLglM5Ytg9tuCw8bly2D730vHGSw555JJxPJOypu2TQNDXDPPTBkCHzwQThBfeBA2HffpJOJ5C1NB5SN8+mncO+90KVLOHGmvDzMzR43TqUtkmW645aWWb0aRo0K+2C/+244QX3MmLD6UURahe64JT1r1sATT8B++8G554bzHCdO/GzJuoi0GhW3bJg7PPssHHggnH56WI4+blwYFqmo0AZQIglodqjEzHYFHgF2AhwY7u53ZDuY5ICXXoJrr4XXXgtj2aNGhePCItxLZML0OoZNqmVRfQPtS4qprCijT48OSccS2SjpjHGvBn7u7tPMbBug2sxecPdZWc4mSZkyBa67Dl58ETp2hOHD4Yc/hKKipJNtlAnT6+g/roaGxiYA6uob6D+uBkDlLVFqdqjE3d9z92mpr5cB7wD6056P3nwznOd46KFhM6jbbw97jFx4YbSlDTBsUu1/S3uthsYmhk2qTSiRyKZp0Ri3mXUGegBT1/HP+ppZlZlVLVmyJDPppHXU1obx6/33h1degV/+EubNC5tAbbll0uk22aL6hha9LpLr0i5uM2sHPAVc5u4f/+8/d/fh7l7u7uWlpaWZzCjZ8u67YYZIt27hiLDrroN//AOuuQbatUs6Xca0Lylu0esiuS6t4jazIkJpP+ru47IbSbLuvffCpk977w2jR8Nll4XCHjQISkqSTpdxlRVlFBd98YFqcVEbKivKEkoksmnSmVViwAPAO+7+6+xHkqxZuhSGDoW77w4LaS64INxld8jvRxZrH0BqVonki3RmlfQEzgZqzGxG6rVr3P2P2YslGfXRR/DrX4dNoFasgLPOCoca7LFH0slaTZ8eHVTUkjeaLW53nwxolUWMPvkk3F0PHRq2Wz311LBUvVu3pJOJyCbQysl8tGpVKOwuXeCqq+BrX4PqanjySZW2SB7QJlP5ZPVqePjhsK3qv/4Fhx8OY8dCz55JJxORDNIddz5YsybMDunWLTxw3HlneP75sGRdpS2Sd1TcMXOHZ54JC2e+972wWObpp8OS9WOO0QZQInlKxR0jd/jTn8LY9cknw8qV8NhjMGNGWLKuwhbJayru2Pztb3DkkeGO+v33YcQImDULzjwTNtPHKVII9JMei2nT4IQT4LDDYPZsuPNOmDMHzj8f2uoZs0ghUXHnulmzwvzrAw8MY9dDhoQNoH76U9hii6TTiUgCdKuWq+bPD4tlRo2CrbaCG26Ayy+H7bZLOpmIJEzFnWvq6sJmTw88EIZALr88LKLZYYekk4lIjlBx54olS8IwyD33hHnZffuGY8Pat086mYjkGBV30urr4dZbw2kzn3wCP/hB2ACqc+ekk4lIjlJxJ2X5crjrLvjVr0J5n3ZaGNPu2jXpZCKS41TcrW3lSvjtb2HwYFi8GHr3DmPa+++fdDIRiYSmA7aWxka4/37Yay/o1w/23RdefRV+/3uVtoi0iIo725qa4NFHYZ99wgPHjh3hxRfDX4cemnQ6EYmQijtb3GH8eOjePZw4065duLt+9VU46qik04lIxFTcmeYOEyfCQQfBKaeEPbIffzwsWe/dWxtAicgmU3Fn0iuvhMMLjj8+HMz74IMwc2aYMaINoEQkQ9QmmVBVBccdB716wdy5YRHNnDnwwx9qAygRyTgV96aYOTMMhxx0UCjvYcNCcV90EWy+edLpRCRP6XZwY8ydG1Y3jh4dHjoOGACXXQbbbpt0MhEpACrulliwICyWGTky3FFXVsKVV8L22yedTEQKiIq7JV58MZyiftFFcM014VBeEZFWpuJuibPOCnOwO3VKOomIFDA9nGyJtm1V2iKSOBW3iEhkmi1uMxtpZovNbGZrBBIRkQ1LZ4z7IeBu4JHsRsltE6bXMWxSLYvqG2hfUkxlRRl9enRIOpaIFKBmi9vdXzazztmPkrsmTK+j/7gaGhqbAKirb6D/uBoAlbeItDqNcadh2KTa/5b2Wg2NTQybVJtQIhEpZBkrbjPra2ZVZla1ZMmSTP22OWFRfUOLXhcRyaaMFbe7D3f3cncvLy0tzdRvmxPalxS36HURkWzSUEkaKivKKC5q84XXiovaUFlRllAiESlk6UwHHA28BpSZ2UIzOz/7sXJLnx4dGHzKfnQoKcaADiXFDD5lPz2YFJFEpDOr5MzWCJLr+vTooKIWkZygoRIRkciouEVEIqPiFhGJjIpbRCQyKm4RkciouEVEIqPiFhGJjIpbRCQyKm4RkciouEVEIqPiFhGJjIpbRCQyKm4RkciouEVEIqPiFhGJjIpbRCQyKm4RkciouEVEIqPiFhGJjIpbRCQyKm4RkciouEVEIqPiFhGJjIpbRCQyKm4RkciouEVEIqPiFhGJjIpbRCQyaRW3mR1nZrVmNtfMrs52KBERWb9mi9vM2gD3AMcD3YAzzaxbtoOJiMi6pXPHfTAw193nu/unwBjg5OzGEhGR9WmbxjUdgAWf+34hcMj/XmRmfYG+qW9XmdnMTY+Xk3YAliYdIov0/uKm9xevsnQvTKe40+Luw4HhAGZW5e7lmfq9c0k+vzfQ+4ud3l+8zKwq3WvTGSqpA3b93PcdU6+JiEgC0inuN4C9zGx3M9scOAN4JruxRERkfZodKnH31WZ2CTAJaAOMdPe3m/llwzMRLkfl83sDvb/Y6f3FK+33Zu6ezSAiIpJhWjkpIhIZFbeISGQyWtz5vDTezEaa2eJ8nZ9uZrua2UtmNsvM3jazS5POlElmtqWZvW5mb6be34CkM2WambUxs+lm9mzSWTLNzN41sxozm9GSaXOxMLMSMxtrZrPN7B0zO3SD12dqjDu1NH4OcAxhkc4bwJnuPisj/wMJM7NewHLgEXffN+k8mWZmuwC7uPs0M9sGqAb65NHnZ8DW7r7czIqAycCl7j4l4WgZY2aXA+XAtu7eO+k8mWRm7wLl7p6Xi2/M7GHgFXcfkZq9t5W716/v+kzecef10nh3fxn4MOkc2eLu77n7tNTXy4B3CKtm84IHy1PfFqX+ypsn82bWEfgWMCLpLNIyZrYd0At4AMDdP91QaUNmi3tdS+Pz5ge/kJhZZ6AHMDXZJJmVGkqYASwGXnD3fHp/twNXAmuSDpIlDjxvZtWp7TXyye7AEuDB1FDXCDPbekO/QA8n5QvMrB3wFHCZu3+cdJ5Mcvcmd9+fsPr3YDPLiyEvM+sNLHb36qSzZNFh7n4AYZfSi1NDl/miLXAA8Bt37wGsADb4jDCTxa2l8ZFLjf0+BTzq7uOSzpMtqf8MfQk4LuksGdITOCk1DjwGOMrMRiUbKbPcvS7198XAeMLQbL5YCCz83H8BjiUU+Xplsri1ND5iqYd3DwDvuPuvk86TaWZWamYlqa+LCQ/RZyebKjPcvb+7d3T3zoSfuz+7+1kJx8oYM9s69cCc1BDCsUDezO5y9/eBBWa2dnfAo4ENTgrI5O6AG7M0PhpmNho4AtjBzBYCN7r7A8mmyqiewNlATWocGOAad/9jgpkyaRfg4dTsp82AJ9w976bN5amdgPHh3oK2wGPuPjHZSBn3U+DR1E3vfODcDV2sJe8iIpHRw0kRkciouEVEIqPiFhGJjIpbRCQyKm4RkciouEVEIqPiFhGJzP8BY2wsssa/wh8AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1064f7ef0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x,y)\n",
    "plt.axis([0,6,0,6])\n",
    "\n",
    "# X = np.linspace(0,6,100)\n",
    "# plt.plot(X, X*a+b)\n",
    "y_hat = a*x + b\n",
    "plt.plot(x, y_hat, color='r')\n",
    "\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用我们自己的Simple Linear Regression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SimpleLinearRegression1()"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from c2_linear_regression.simple_linear_regression import SimpleLinearRegression1\n",
    "\n",
    "reg1 = SimpleLinearRegression1()\n",
    "reg1.fit(x, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.2000000000000002"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_predict = 6\n",
    "y_predict = a*x_predict + b\n",
    "y_predict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 5.2])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reg1.predict(np.array([x_predict]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.80000000000000004"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reg1.a_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.39999999999999947"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reg1.b_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 向量化实现的Simple Linear Regression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "from c2_linear_regression.simple_linear_regression import SimpleLinearRegression2\n",
    "reg2 = SimpleLinearRegression2()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 5.2])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reg2.fit(x,y)\n",
    "reg2.predict(np.array([x_predict]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.80000000000000004"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reg2.a_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.39999999999999947"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reg2.b_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 向量化实现的性能测试\n",
    "首先创建一个比较大的测试数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = 1000000\n",
    "big_x = np.random.random(size=m)\n",
    "# 让y加上一个正态随机分布的干扰值\n",
    "big_y = big_x * 2.0 +3.0 + np.random.normal(size=m)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "第一个是for循环，第二个是向量化运算，看看运行时间"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "855 ms ± 13.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "18.6 ms ± 2.81 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit reg1.fit(big_x, big_y)\n",
    "%timeit reg2.fit(big_x, big_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.9984020404339247"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reg1.a_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.000104500930747"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reg1.b_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.9984020404337848"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reg2.a_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.0001045009308172"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reg2.b_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
